home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / Kibitz / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  13.5 KB  |  495 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        menu.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20. #ifndef __DESK__
  21. #include <Desk.h>
  22. #endif
  23.  
  24. #ifndef __ERRORS__
  25. #include <Errors.h>
  26. #endif
  27.  
  28. #ifndef __MENUS__
  29. #include <Menus.h>
  30. #endif
  31.  
  32. #ifndef __STRING__
  33. #include <String.h>
  34. #endif
  35.  
  36. #ifndef __TEXTEDITCONTROL__
  37. #include <TextEditControl.h>
  38. #endif
  39.  
  40. #ifndef __TOOLUTILS__
  41. #include <ToolUtils.h>
  42. #endif
  43.  
  44. #ifndef __UTILITIES__
  45. #include <Utilities.h>
  46. #endif
  47.  
  48.  
  49.  
  50. /*****************************************************************************/
  51.  
  52.  
  53.  
  54. extern Boolean    gQuitApplication;
  55. extern Boolean    gHasAppleEvents;
  56. extern Boolean    gHasPPCToolbox;
  57. extern Boolean    gSendToSelf;
  58. extern short    gReplyMode;
  59.  
  60.  
  61.  
  62. /*****************************************************************************/
  63. /*****************************************************************************/
  64.  
  65.  
  66.  
  67. /* Enable and disable menus based on the current state.  The user can only
  68. ** select enabled menu items.  We set up all the menu items before calling
  69. ** MenuSelect or MenuKey, since these are the only times that a menu item can
  70. ** be selected.  Note that MenuSelect is also the only time the user will see
  71. ** menu items.  This approach to deciding what enable/ disable state a menu
  72. ** item has the advantage of concentrating all the decision-making in one
  73. ** routine, as opposed to being spread throughout the application.  Other
  74. ** application designs may take a different approach that is just as valid. */
  75.  
  76. #pragma segment Menu
  77. void    AdjustMenus(void)
  78. {
  79.     WindowPtr        window;
  80.     MenuHandle        menu;
  81.     short            numWindows, activeItem;
  82.     Boolean            maxWindows, menuEnabled, redrawMenuBar, winIsDirty, fileIsOpen;
  83.     TEHandle        teHndl;
  84.     Rect            rct;
  85.     FileRecHndl        frHndl;
  86.     static Boolean    editMenuEnabled = true;
  87.     static Boolean    gameMenuEnabled = true;
  88.  
  89.     redrawMenuBar = false;
  90.     window = FrontWindow();
  91.  
  92.     if (IsAppWindow(window)) frHndl = (FileRecHndl)GetWRefCon(window);
  93.  
  94.     menu = GetMHandle(mFile);
  95.  
  96.     EnableItem(menu, iNew);                /* Set these for the no-windows state. */
  97.     EnableItem(menu, iOpen);
  98.     EnableItem(menu, iMessage);
  99.     if (MaxBlock() < 0x10000L) {
  100.         if (CompactMem(0x10000L) < 0x10000L) {
  101.             DisableItem(menu, iNew);    /* Running low on RAM. */
  102.             DisableItem(menu, iOpen);
  103.         }
  104.     }
  105.  
  106.     DisableItem(menu, iClose);
  107.     DisableItem(menu, iSave);
  108.     DisableItem(menu, iSaveAs);
  109.     DisableItem(menu, iDuplicate);
  110.     DisableItem(menu, iRevert);
  111.     DisableItem(menu, iPageSetup);
  112.     DisableItem(menu, iPrint);
  113.         /* Quit is always hilited. */
  114.  
  115.  
  116.  
  117.     if (IsDAWindow(window)) {
  118.         DisableItem(menu, iNew);        /* DAs don't get to do a new. */
  119.         DisableItem(menu, iOpen);        /* DAs don't get to do an open. */
  120.         DisableItem(menu, iMessage);    /* DAs don't get to do a new. */
  121.         EnableItem(menu, iClose);        /* Let DAs do a close from the menu. */
  122.     }
  123.  
  124.     if (IsAppWindow(window)) {
  125.         numWindows = GetWindowCount(false, false, false);
  126.         maxWindows = (numWindows < kMaxNumWindows);
  127.         EnableOrDisableItem(menu, iNew, maxWindows);
  128.         EnableOrDisableItem(menu, iOpen, maxWindows);
  129.         EnableOrDisableItem(menu, iMessage, maxWindows);
  130.             /* Allow a new and open only if max number of files not reached. */
  131.  
  132.         winIsDirty = AppWindowDirty(window);
  133.         fileIsOpen = ((*frHndl)->fileState.fss.vRefNum != kInvalVRefNum);
  134.  
  135.         EnableItem(menu, iClose);
  136.         EnableOrDisableItem(menu, iSave, winIsDirty);
  137.         EnableItem(menu, iSaveAs);
  138.         if ((*frHndl)->doc.myColor == kMessageDoc) EnableItem(menu, iSaveBoardImage);
  139.         EnableItem(menu, iDuplicate);
  140.         EnableOrDisableItem(menu, iRevert, ((winIsDirty) && (fileIsOpen)));
  141.  
  142.         EnableItem(menu, iPageSetup);
  143.         EnableItem(menu, iPrint);
  144.     }
  145.  
  146.  
  147.  
  148.     menu = GetMHandle(mEdit);
  149.     DisableItem(menu, iSelectAll);
  150.     if (IsDAWindow(window)) {        /* A desk accessory may need edit menu. */
  151.         menuEnabled = true;
  152.         EnableItem(menu, iUndo);
  153.         EnableItem(menu, iCut);
  154.         EnableItem(menu, iCopy);
  155.         EnableItem(menu, iPaste);
  156.         EnableItem(menu, iClear);
  157.     } else {
  158.         menuEnabled = false;
  159.         if (window) {
  160.             CTEEditMenu(&menuEnabled, mEdit, iUndo, iCut);
  161.             if (CTETargetInfo(&teHndl, &rct) == window) {
  162.                 if ((*teHndl)->teLength) {
  163.                     EnableItem(menu, iSelectAll);
  164.                     menuEnabled = true;
  165.                 }
  166.             }
  167.         }
  168.     }
  169.     if (editMenuEnabled != menuEnabled) {
  170.         redrawMenuBar = true;
  171.         if (editMenuEnabled = menuEnabled) EnableItem(menu, 0);
  172.         else                               DisableItem(menu, 0);
  173.     }
  174.  
  175.  
  176.  
  177.     menu = GetMHandle(mGame);                /* Start by disabling everything. */
  178.     menuEnabled = false;
  179.     DisableItem(menu, iConfigureGame);
  180.     DisableItem(menu, iInvertBoard);
  181.     DisableItem(menu, iArrangeBoard);
  182.     DisableItem(menu, iPlayOnePlayer);
  183.     DisableItem(menu, iPlayTwoPlayer);
  184.     DisableItem(menu, iFindTwoPlayer);
  185.     DisableItem(menu, iGoToMove);
  186.     DisableItem(menu, iAlgOut);
  187.     DisableItem(menu, iAlgIn);
  188.  
  189.     CheckItem(menu, iArrangeBoard, false);
  190.     CheckItem(menu, iPlayOnePlayer, false);
  191.     CheckItem(menu, iPlayTwoPlayer, false);
  192.     CheckItem(menu, iFindTwoPlayer, false);
  193.  
  194.     if (IsAppWindow(window)) {
  195.  
  196.         if (!(*frHndl)->fileState.readOnly) {
  197.  
  198.             if ((*frHndl)->doc.myColor != kMessageDoc) {
  199.  
  200.                 menuEnabled = true;
  201.  
  202.                 if (!(*frHndl)->doc.arrangeBoard) {
  203.                     EnableItem(menu, iConfigureGame);
  204.                     EnableItem(menu, iArrangeBoard);
  205.                 }
  206.                 EnableItem(menu, iInvertBoard);
  207.                 EnableItem(menu, iPlayOnePlayer);
  208.                 if (gHasAppleEvents) {                /* Now the 7.0 goodie... */
  209.                     EnableItem(menu, iPlayTwoPlayer);
  210.                     EnableItem(menu, iFindTwoPlayer);
  211.                 }
  212.  
  213.                 if ((*frHndl)->doc.numGameMoves)
  214.                     EnableItem(menu, iGoToMove);
  215.  
  216.                 if ((*frHndl)->doc.gameIndex < (*frHndl)->doc.numGameMoves)
  217.                     EnableItem(menu, iAlgOut);
  218.  
  219.                 teHndl = (*frHndl)->doc.message[kMessageOut];
  220.                 if ((*teHndl)->selStart != (*teHndl)->selEnd)
  221.                     EnableItem(menu, iAlgIn);
  222.  
  223.                 activeItem = iPlayOnePlayer + (*frHndl)->doc.twoPlayer;
  224.                 if ((*frHndl)->doc.arrangeBoard) activeItem = iArrangeBoard;
  225.                 DisableItem(menu, activeItem);
  226.                 if (activeItem == iPlayTwoPlayer) DisableItem(menu, iFindTwoPlayer);
  227.                 CheckItem(menu, activeItem, true);
  228.             }
  229.         }
  230.     }
  231.     if (gameMenuEnabled != menuEnabled) {
  232.         redrawMenuBar = true;
  233.         if (gameMenuEnabled = menuEnabled)
  234.              EnableItem(menu, 0);
  235.         else DisableItem(menu, 0);
  236.     }
  237.  
  238.     if (redrawMenuBar) DrawMenuBar();
  239. }
  240.  
  241.  
  242.  
  243. /*****************************************************************************/
  244.  
  245.  
  246.  
  247. /* This function either enables or disables a menu item. */
  248.  
  249. #pragma segment Menu
  250. void    EnableOrDisableItem(MenuHandle menu, short item, Boolean enable)
  251. {
  252.     if (enable) EnableItem(menu, item);
  253.     else        DisableItem(menu, item);
  254. }
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259.  
  260.  
  261.  
  262. /* This is called when an item is chosen from the menu bar (after calling
  263. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  264. ** It is good to have both the result of MenuSelect and MenuKey go to one
  265. ** routine like this to keep everything organized. */
  266.  
  267. #pragma segment Menu
  268. void    DoMenuCommand(long menuResult, EventRecord *event)
  269. {
  270.     short        menuID;            /* The resource ID of the selected menu. */
  271.     short        menuItem;        /* The item number of the selected menu. */
  272.     Str255        daName;
  273.     short        daRefNum, arrangeBoard;
  274.     FileRecHndl    frHndl, newFrHndl;
  275.     OSErr        err;
  276.     WindowPtr    window, oldPort;
  277.     short        itemHit;
  278.     DialogPtr    dlg;
  279.     StringPtr    nbpType;
  280.     TEHandle    teHndl;
  281.     Rect        rct;
  282.  
  283.     if (window = FrontWindow())
  284.         frHndl = (FileRecHndl)GetWRefCon(window);
  285.             /* frHndl is valid only if it is one of our windows. */
  286.  
  287.     menuID = HiWord(menuResult);    /* Use macros for efficiency to get */
  288.     menuItem = LoWord(menuResult);    /* menu item number and menu number. */
  289.  
  290.     switch (menuID) {
  291.  
  292.         case mApple:
  293.             switch (menuItem) {
  294.                 case iAbout:    /* Bring up alert for About. */
  295.                     Alert(rAboutAlert, (ModalFilterProcPtr)AlertFilter);
  296.                     break;
  297.                 default:        /* All non-About items in this menu are DAs. */
  298.                     GetItem(GetMHandle(mApple), menuItem, daName);
  299.                     daRefNum = OpenDeskAcc(daName);
  300.                     break;
  301.             }
  302.             break;
  303.  
  304.         case mFile:
  305.             switch (menuItem) {
  306.                 case iNew:
  307.                     err = AppNewDocument(&frHndl, ksOrigName);
  308.                     if (!err) {
  309.                         (*frHndl)->doc.compMovesBlack = true;
  310.                         if (err = AppNewWindow(frHndl, nil, (WindowPtr)-1))
  311.                             AppDisposeDocument(frHndl);
  312.                     }
  313.                     if (err) Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  314.                     break;
  315.                 case iOpen:
  316.                     err = AppOpenDocument(&frHndl, nil, fsRdWrPerm);
  317.                     if (!err) {
  318.                         if (err = AppNewWindow(frHndl, nil, (WindowPtr)-1))
  319.                             AppDisposeDocument(frHndl);
  320.                         else
  321.                             AppAutoLaunch(frHndl);
  322.                     }
  323.                     if ((err) && (err != userCanceledErr))
  324.                         Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  325.                     break;
  326.                 case iMessage:
  327.                     err = AppNewDocument(&frHndl, ksMssgName);
  328.                     if (!err) {
  329.                         if (err = AppNewWindow(frHndl, nil, (WindowPtr)-1))
  330.                             AppDisposeDocument(frHndl);
  331.                     }
  332.                     if (err) Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  333.                     break;
  334.                 case iClose:
  335.                     CloseOneWindow(window, iClose);
  336.                     break;
  337.                 case iSave:
  338.                     err = AppSaveDocument(frHndl, window, iSave);
  339.                     if ((err) && (err != userCanceledErr))
  340.                         Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  341.                     break;
  342.                 case iSaveAs:
  343.                     err = AppSaveDocument(frHndl, window, iSaveAs);
  344.                     if ((err) && (err != userCanceledErr))
  345.                         Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  346.                     break;
  347.                 case iSaveBoardImage:
  348.                     err = SaveBoardImage(frHndl);
  349.                     if ((err) && (err != userCanceledErr))
  350.                         Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  351.                     break;
  352.                 case iDuplicate:
  353.                     err = AppDuplicateDocument(frHndl, &newFrHndl);
  354.                     if (!err) {
  355.                         if (err = AppNewWindow(newFrHndl, nil, (WindowPtr)-1))
  356.                             AppDisposeDocument(newFrHndl);
  357.                     }
  358.                     if (err) Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  359.                     break;
  360.                 case iRevert:
  361.                     DoSetCursor(&qd.arrow);
  362.                     if (dlg = GetCenteredDialog(rRevertWarning, nil,
  363.                                                 FrontWindow(), (WindowPtr)-1L)) {
  364.                         OutlineDialogItem(dlg, 1);
  365.                         ModalDialog((ModalFilterProcPtr)KeyEquivFilter, &itemHit);
  366.                         DisposeDialog(dlg);
  367.                         if (itemHit == 3) break;
  368.                     }
  369.                     if ((*frHndl)->doc.twoPlayer) SetOpponentType(frHndl, kOnePlayer);
  370.                     if (!(AppReadDocument(frHndl, gameFileType))) {
  371.                         arrangeBoard = (*frHndl)->doc.arrangeBoard;
  372.                         if (arrangeBoard)
  373.                             if (CTETargetInfo(&teHndl, &rct) == window)
  374.                                 CTEActivate(false, teHndl);
  375.                         oldPort = SetFilePort(frHndl);
  376.                         rct = window->portRect;
  377.                         EraseRect(&rct);
  378.                         ImageDocument(frHndl, false);
  379.                         if (!arrangeBoard) AdjustGameSlider(frHndl);
  380.                         UpdateGameStatus(frHndl);
  381.                         DrawTime(frHndl);
  382.                         SetPort(oldPort);
  383.                         if (!arrangeBoard) CTEWindActivate(window);
  384.                     }
  385.                     break;
  386.                 case iPageSetup:
  387.                     DoSetCursor(&qd.arrow);
  388.                     PresentStyleDialog(frHndl);
  389.                     break;
  390.                 case iPrint:
  391.                     DoSetCursor(&qd.arrow);
  392.                     err = noErr;
  393.                     if (!(*frHndl)->doc.printRecValid)
  394.                         err = PresentStyleDialog(frHndl);
  395.                     if (!err) {
  396.                         err = AppPrintDocument(frHndl, true, true);
  397.                         AppPrintDocument(nil, false, false);
  398.                     }
  399.                     if ((err) && (err != userCanceledErr))
  400.                         Alert(rErrorAlert, (ModalFilterProcPtr)AlertFilter);
  401.                     break;
  402.                 case iQuit:
  403.                     gQuitApplication = CloseAllWindows();
  404.                     break;
  405.             }
  406.             break;
  407.  
  408.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  409.             if (IsAppWindow(window)) {
  410.                 switch (menuItem) {
  411.                     case iUndo:
  412.                         CTEUndo();
  413.                         break;
  414.                     case iCut:
  415.                     case iCopy:
  416.                     case iPaste:
  417.                     case iClear:
  418.                         CTEClipboard(menuItem - iCut + 2);
  419.                         if (menuItem != iCopy) (*frHndl)->fileState.docDirty = true;
  420.                         break;
  421.                     case iSelectAll:
  422.                         if (CTETargetInfo(&teHndl, &rct) == window) CTESetSelect(0, 32000, teHndl);
  423.                         break;
  424.                 }
  425.             }
  426.             else SystemEdit(menuItem - 1);
  427.             break;
  428.  
  429.         case mGame:
  430.             switch (menuItem) {
  431.                 case iConfigureGame:
  432.                     DoSetCursor(&qd.arrow);
  433.                     DoConfigureGame(frHndl);
  434.                     break;
  435.                 case iInvertBoard:
  436.                     (*frHndl)->doc.invertBoard ^= 1;
  437.                     if (!(*frHndl)->doc.twoPlayer) {
  438.                         if ((*frHndl)->doc.compMovesWhite + (*frHndl)->doc.compMovesBlack == 1) {
  439.                             if ((*frHndl)->doc.compMovesWhite == (*frHndl)->doc.myColor) {
  440.                                 (*frHndl)->doc.compMovesWhite ^= true;
  441.                                 (*frHndl)->doc.compMovesBlack ^= true;
  442.                                 (*frHndl)->doc.myColor        ^= true;
  443.                             }
  444.                         }
  445.                     }
  446.                     SetPort(window);
  447.                     ImageDocument(frHndl, true);
  448.                     DrawTime(frHndl);
  449.                     break;
  450.                 case iArrangeBoard:
  451.                 case iPlayOnePlayer:
  452.                 case iPlayTwoPlayer:
  453.                 case iFindTwoPlayer:
  454.                     DoSetCursor(&qd.arrow);
  455.                     if ((menuItem == iArrangeBoard) && ((*frHndl)->doc.numGameMoves)) {
  456.                         if (dlg = GetCenteredDialog(rArrangeWarning, nil,
  457.                                                     FrontWindow(), (WindowPtr)-1L)) {
  458.                             OutlineDialogItem(dlg, 1);
  459.                             ModalDialog((ModalFilterProcPtr)KeyEquivFilter, &itemHit);
  460.                             DisposeDialog(dlg);
  461.                             if (itemHit == 3) break;
  462.                         }
  463.                     }
  464.                     nbpType = nil;
  465.                     if (menuItem == iFindTwoPlayer) {
  466.                         menuItem = iPlayTwoPlayer;
  467.                         nbpType = "\pKibitz";
  468.                     }
  469.                     if (menuItem == iPlayTwoPlayer) {
  470.                         if (!(*frHndl)->doc.twoPlayer) SendGame(frHndl, kIsMove, nbpType);
  471.                     }
  472.                     else SetOpponentType(frHndl, menuItem - iPlayOnePlayer + kOnePlayer);
  473.                     break;
  474.                 case iGoToMove:
  475.                     DoGoToMove(frHndl);
  476.                     break;
  477.                 case iAlgOut:
  478.                     DoSetCursor(*GetCursor(watchCursor));
  479.                     MovesToOutBox(frHndl, event);
  480.                     break;
  481.                 case iAlgIn:
  482.                     DoSetCursor(*GetCursor(watchCursor));
  483.                     MovesFromOutBox(frHndl);
  484.                     break;
  485.             }
  486.             break;
  487.  
  488.     }
  489.  
  490.     HiliteMenu(0);        /* Unhighlight what MenuSelect (or MenuKey) hilited. */
  491. }
  492.  
  493.  
  494.  
  495.